home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
net3d-0.08
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-22
|
25KB
|
1,094 lines
/* file.c
*
* Functions for reading in a vehicle from a file
*/
#include "net3d.h"
static char *ownernames[OWNERCOUNT] = { "player",
"game",
"network",
"none" };
static char *weaponnames[WEAPONCOUNT] = {"none",
"tracer",
"shell",
"bullet",
"bomb",
"flame",
"missile",
"chicken",
"plasmaballs",
"torpedo"};
static char *typenames[TYPECOUNT] = {"tank",
"fish",
"bird",
"shrapnel",
"static",
"bullet",
"hover",
"scenery",
"fixedwing",
"thing",
"missile",
"tree",
"seedpod",
"gunsite",
"mine",
"weapon",
"munitions",};
int linenum; /* line up to in reading a file desc. */
static char *filename; /* name of file being read */
static pid_t childpid = 0; /* current child process being used
* for piping */
/* reads the next token from the input file, allowing for comments */
void ntoken(int fp, char *s)
{
/* zero string, and read in a new one (hopefully) */
s[0]='\0';
strcpy(s,ngetw(fp));
/* printf("%s\n",s); */
/* anything inside a standard c-style comment is ignored */
if (!strcmp(s,"/*")) {
while(strcmp(s,"*/"))
ntoken(fp,s);
ntoken(fp,s);
}
/* a line beginning with # is from cpp, and gives the line number and
* maybe the file name.
*/
if (!strcmp(s,"#")) {
char *cppinfo;
char *lnum, *fname;
cppinfo = ngets(fp);
lnum = strtok(cppinfo," \t");
linenum = atoi(lnum) - 1;
if ((fname = strtok(NULL," \t"))) {
/* A file name is provided */
filename = strdupe(fname);
}
ntoken(fp,s);
}
}
/* duplicates some memory */
void *dupe(void *mem, int size)
{
void *newm;
newm=(void *)malloc(size);
memcpy(newm,mem,size);
return newm;
}
/* duplicates a string */
char *strdupe(char *s)
{
char *news;
if (s) {
news=(char *)malloc(strlen(s)+1);
strcpy(news,s);
return news;
}
else
return NULL;
}
/* prints an error encountered during parsing of 3d input file */
void fileerror(char *msg, char *tok, int fp)
{
fprintf(stderr,"Vehicle file error at line %d in %s:\n",linenum,filename);
fprintf(stderr,"%s : %s\n",msg,tok);
close(fp);
if (childpid) {
/* If a child process has been forked to pipe a vehicle file
* though cpp, kill it. */
kill(childpid,SIGTERM);
}
exit(1);
}
/* reads a file containing 3-d definitions of vehicles, each made
* up of a number of objects */
void readfile(struct object **ohead, struct vehicle **vhead, int fp,
struct map *mp)
{
char tok[100]={0};
struct vehicle *nv;
struct object *no;
int end=0;
struct vehicle **dvhead;
struct object **dohead;
linenum = 1;
filename = "unknown";
dvhead = &evhead;
dohead = &eohead;
/* note - need code to handle errors in vehicle file */
while(!end) {
ntoken(fp,tok);
if (!strcmp(tok,"vehicle")) {
/* create a new vehicle */
int endv=0;
float xoff=0,yoff=0,zoff=0;
bool def=false;
#if DEBUG
printf("Reading vehicle\n");
#endif
nv=(struct vehicle *)calloc(1,sizeof(struct vehicle));
nv->partcount=0;
nv->parts=(struct object **)calloc(MAX_PARTS_PER_VEHICLE,
sizeof(struct object *));
nv->owner = o_game;
nv->type = t_bird;
nv->weapon = w_none;
nv->velocity = 0.0;
nv->angle = 0.0;
nv->angle_vel = 0.0;
nv->turret_ang = 0.0;
nv->flying = false;
nv->hp = 5;
nv->alive = true;
nv->vid = vidcount++;
nv->target = -1;
nv->reload = 0;
nv->range = 0;
nv->max.velocity = vmax[nv->type];
nv->max.angle_vel = MAX_ANGLE_VEL;
nv->max.altitude = MAX_ALTITUDE;
nv->max.turret_ang = MAX_TURRET_ANG;
nv->max.treeheight = 40;
nv->lock = -1;
nv->transfer = -1;
nv->missile = -1;
nv->ammo = 20;
nv->res = 0;
nv->vm9vid = -1;
nv->buildervid = -1;
nv->seed = NULL;
nv->pnum = -1;
nv->stcount = 0;
nv->states = calloc(MAX_STATES_PER_VEHICLE,
sizeof(struct state **));
nv->currentstate = -1;
nv->lasthit = -1.0;
nv->lastvid = -1;
nv->ftimer = 0.0;
nv->bumped = False;
/* read vehicle name */
ntoken(fp,tok);
nv->code=(char *)malloc(strlen(tok)+1);
strcpy(nv->code,tok);
/* check for { or def */
ntoken(fp,tok);
if (!strcmp(tok,"def")) {
/* this is a definition only */
def = true;
nv->next = (*dvhead);
(*dvhead) = nv;
ntoken(fp,tok);
}
else if (!strcmp(tok,"{")) {
nv->next=(*vhead);
(*vhead)=nv;
}
#if DEBUG
printf("reading in %s\n",tok);
#endif
while(!endv) {
ntoken(fp,tok);
if (!strcmp(tok,"name")) {
/* read vehicle name */
char name[100];
int i=0;
char futplex;
#if DEBUG
printf("Reading name\n");
#endif
read(fp,&futplex,1); /* skip " */
do {
read(fp,name+i,1);
} while(name[i++] != '\"');
name[i-1]='\0';
nv->name=(char *)malloc(strlen(name)+1);
strcpy(nv->name,name);
}
else if (!strcmp(tok,"object")) {
/* read in an object of this vehicle */
int endo=0;
float xo=0,yo=0,zo=0;
if (nv->partcount >= MAX_PARTS_PER_VEHICLE)
fileerror("Maximum objects per "
"vehicle limit reached","",fp);
#if DEBUG
printf("Reading object\n");
#endif
no = (struct object *)calloc(1,sizeof(
struct object));
no->cent.x = no->cent.y=no->cent.z=0.0;
no->pcount = 0;
no->fcount = 0;
no->parent = nv;
no->faces = (struct polygon *)calloc(
MAX_FACES_PER_OBJECT,
sizeof(struct polygon));
no->clockwise = true;
no->angle_vel = 0.0;
no->oscli = (struct oscillate *)calloc(
MAX_OSCLI_PER_OBJECT,
sizeof(struct oscillate));
no->cvalid = false;
no->mightsave = false;
nv->parts[nv->partcount++]=no;
/* If this object is part of a vehicle
* definition, add it to the def's
* object list.
*/
if (def) {
no->next = (*dohead);
(*dohead) = no;
}
else {
no->next=(*ohead);
(*ohead)=no;
}
ntoken(fp,tok);
while(!endo) {
ntoken(fp,tok);
if (!strcmp(tok,"at")) {
#if DEBUG
printf("Reading at\n");
#endif
ntoken(fp,tok);
no->pos.x=atof(tok);
ntoken(fp,tok);
no->pos.y=atof(tok);
ntoken(fp,tok);
no->pos.z=atof(tok);
no->dist=0.0;
}
else if (!strcmp(tok,"centre")) {
#if DEBUG
printf("reading "
"centre\n");
#endif
ntoken(fp,tok);
no->cent.x=atof(tok);
ntoken(fp,tok);
no->cent.y=atof(tok);
ntoken(fp,tok);
no->cent.z=atof(tok);
}
else if (!strcmp(tok,"points")) {
/* read in object points */
ntoken(fp,tok);
readpoints(no,fp);
}
else if (!strcmp(tok,"face")) {
/* read in a face */
readface(no,fp);
}
else if (!strcmp(tok,"counter")) {
no->clockwise=false;
}
else if (!strcmp(tok,"angle_velocity")){
ntoken(fp,tok);
no->angle_vel=dtor(atof(tok));
}
else if (!strcmp(tok,"offset")) {
/* add offset to an object */
ntoken(fp,tok);
xo=atof(tok);
ntoken(fp,tok);
yo=atof(tok);
ntoken(fp,tok);
zo=atof(tok);
}
else if (!strcmp(tok,"oscli") ||
!strcmp(tok,"bounce")) {
int o;
if (no->ocount >=
MAX_OSCLI_PER_OBJECT)
fileerror("Maximum "
"oscli per object "
"limit reached","",fp);
o=no->ocount++;
/* oscillation function */
if (tok[0]=='o') {
no->oscli[o].func =
sinhalf;
}
else if (tok[0]=='b') {
no->oscli[o].func =
sinsq;
}
/* point to oscillate */
ntoken(fp,tok);
if (atoi(tok) == -1) {
no->oscli[o].pt =
&(no->pos);
}
else {
no->oscli[o].pt =
&(no->points[atoi(tok)]);
}
no->oscli[o].pnum = atoi(tok);
no->oscli[o].init =
*(no->oscli[o].pt);
/* oscillation rate */
ntoken(fp,tok);
no->oscli[o].rate=atof(tok);
/* get oscli vector
* and axis flags
*/
/* read { or phase */
ntoken(fp,tok);
if (tok[0]!='{') {
no->oscli[o].phase
= dtor(atof(tok));
ntoken(fp,tok);
}
/* x axis */
ntoken(fp,tok);
if (strcmp(tok,"-")) {
no->oscli[o].ovec.x
= atof(tok);
no->oscli[o].axes |=
OSC_X_AXIS;
}
/* y axis */
ntoken(fp,tok);
if (strcmp(tok,"-")) {
no->oscli[o].ovec.y
= atof(tok);
no->oscli[o].axes |=
OSC_Y_AXIS;
}
/* z axis */
ntoken(fp,tok);
if (strcmp(tok,"-")) {
no->oscli[o].ovec.z
= atof(tok);
no->oscli[o].axes |=
OSC_Z_AXIS;
}
ntoken(fp,tok); /* get } */
}
else if (!strcmp(tok,"turret")) {
no->turret=true;
}
else if (!strcmp(tok,"rotate")) {
readrotate(no,fp);
}
else if (!strcmp(tok,"scale")) {
readscale(no,fp);
}
else if (!strcmp(tok,"}")) {
/* apply offsets to object */
int k;
for(k=0; k<no->pcount; k++) {
no->points[k].x += xo;
no->points[k].y += yo;
no->points[k].z += zo;
}
endo=1;
}
else
fileerror("illegal token "
"in object",tok,fp);
}
}
else if (!strcmp(tok,"velocity")) {
#if DEBUG
printf("Reading velocity\n");
#endif
ntoken(fp,tok);
nv->velocity=atof(tok);
}
else if (!strcmp(tok,"angle")) {
#if DEBUG
printf("Reading angle\n");
#endif
ntoken(fp,tok);
nv->angle=dtor(atof(tok));
}
else if (!strcmp(tok,"angle_velocity")) {
#if DEBUG
printf("Reading angle_vel\n");
#endif
ntoken(fp,tok);
nv->angle_vel=dtor(atof(tok));
}
else if (!strcmp(tok,"flying"))
nv->flying=true;
else if (!strcmp(tok,"offset")) {
/* add an offset to a whole vehicle */
ntoken(fp,tok);
xoff=atof(tok);
ntoken(fp,tok);
yoff=atof(tok);
ntoken(fp,tok);
zoff=atof(tok);
}
else if (!strcmp(tok,"copy")) {
/* copy another vehicle for this one.
* makes copies of parts, partcount,
* owner, flying, name, velocity,
* angle & angle_vel */
struct vehicle *copy;
ntoken(fp,tok);
for(copy=*vhead; copy; copy=copy->next)
if (!strcmp(tok,copy->code))
break;
if (!copy)
fileerror("attempted to copy non"
" existant vehicle",tok,fp);
copyvehicle(nv,copy,ohead);
}
else if (!strcmp(tok,"instance")) {
/* this vehicle is an instance of a
* previous definition.
*/
struct vehicle *copy;
ntoken(fp,tok);
for(copy=*dvhead; copy; copy=copy->next)
if (!strcmp(tok,copy->code))
break;
if (!copy)
fileerror("attempted to instance"
"a non-existant definition",tok,fp);
copyvehicle(nv,copy,ohead);
}
else if (!strcmp(tok,"type")) {
int i;
ntoken(fp,tok);
for(i=0; i<TYPECOUNT; i++)
if (!strcmp(tok,typenames[i]))
nv->type = i;
/* If this is a tree, it's default seed
* type is to form another tree.
*/
if (nv->type == t_tree && !nv->seed)
nv->seed = strdupe("tree");
/* assign a max velocity based on
* this type.
*/
nv->max.velocity = vmax[nv->type];
}
else if (!strcmp(tok,"weapon")) {
int i;
ntoken(fp,tok);
for(i=0; i<WEAPONCOUNT; i++)
if (!strcmp(tok,weaponnames[i]))
nv->weapon = i;
}
else if (!strcmp(tok,"hp")) {
ntoken(fp,tok);
nv->hp=atoi(tok);
}
else if (!strcmp(tok,"owner")) {
int i;
ntoken(fp,tok);
for(i=0; i<OWNERCOUNT; i++)
if (!strcmp(tok,ownernames[i]))
nv->owner = i;
}
else if (!strcmp(tok,"spin")) {
readspin(nv,fp);
}
else if (!strcmp(tok,"max")) {
readmax(nv,fp);
}
else if (!strcmp(tok,"seed")) {
ntoken(fp,tok);
nv->seed = strdupe(tok);
}
else if (!strcmp(tok,"ammo")) {
ntoken(fp,tok);
nv->ammo = atoi(tok);
}
else if (!strcmp(tok,"scale")) {
readvehiclescale(nv,fp);
}
else if (!strcmp(tok,"brain")) {
ntoken(fp,tok); /* absorb { */
readbrain(nv,fp);
}
else if (!strcmp(tok,"}")) {
int ob;
endv=1;
/* change all points in the vehicle by
* the amount given by the offsets.
* also set object angles = vehicle
* angle */
for(ob=0; ob<nv->partcount; ob++) {
nv->parts[ob]->pos.x += xoff;
nv->parts[ob]->pos.y += yoff;
nv->parts[ob]->pos.z += zoff;
nv->parts[ob]->angle = nv->angle;
}
/* calculate initial points for all
* oscli's in objects.
*/
for(ob=0; ob<nv->partcount; ob++) {
int os,oc;
oc = nv->parts[ob]->ocount;
for(os=0; os<oc; os++) {
nv->parts[ob]->oscli[os].
init =
*(nv->parts[ob]->oscli[os].
pt);
}
}
}
else
fileerror("illegal token in vehicle",tok,fp);
}
}
else if (!strcmp(tok,"map")) {
int i;
/* map definition */
ntoken(fp,tok); /* read map size */
mp->map_w=atoi(tok);
ntoken(fp,tok);
mp->map_h=atoi(tok);
ntoken(fp,tok); /* read ground size */
mp->size=atof(tok);
ntoken(fp,tok); /* read max height */
mp->scale=atof(tok);
ntoken(fp,tok); /* skip a { */
/* create map array */
mp->gr=(float **)calloc(mp->map_w,sizeof(float *));
for(i=0; i<mp->map_w; i++)
mp->gr[i]=(float *)calloc(mp->map_h,sizeof(float));
/* and height array */
mp->ht=(float **)calloc(mp->map_w,sizeof(float *));
for(i=0; i<mp->map_w; i++)
mp->ht[i]=(float *)calloc(mp->map_h,sizeof(float));
/* read in map from file, a line at a time */
for(i=0; i<mp->map_h; i++) {
int j;
ntoken(fp,tok); /* read a map line */
if (strlen(tok) != mp->map_w)
fileerror("map line is the wrong size",tok,fp);
for(j=0; j<mp->map_w; j++)
mp->gr[j][i]=(tok[j]-65)/57.0*mp->scale;
}
ntoken(fp,tok); /* skip a } */
}
else if (!strcmp(tok,"lookout")) {
/* read vmode 2 watch position */
ntoken(fp,tok);
mp->lookout.x=atof(tok);
ntoken(fp,tok);
mp->lookout.y=atof(tok);
ntoken(fp,tok);
mp->lookout.z=atof(tok);
}
else if (!strcmp(tok,"fadeto")) {
/* world fades to some colour, specified as a triple
* of 16-bit values */
ntoken(fp,tok);
mp->rfade=atoi(tok);
ntoken(fp,tok);
mp->gfade=atoi(tok);
ntoken(fp,tok);
mp->bfade=atoi(tok);
}
else if (!strcmp(tok,"ground")) {
/* colours of the ground and hills.
*/
ntoken(fp,tok);
if (!strcmp(tok,"none")) {
/* No ground! */
mp->ground = False;
}
else {
mp->tcol = atoi(tok);
ntoken(fp,tok);
mp->gcol = atoi(tok);
}
}
else if (!strcmp(tok,"sky")) {
/* Colour of the sky.
*/
ntoken(fp,tok);
mp->skycol = atoi(tok);
}
else if (!strcmp(tok,"stars")) {
/* stars in the sky */
ntoken(fp,tok);
createstars(mp,atoi(tok));
}
else if (!strcmp(tok,"end") || !strlen(tok)) {
end=1;
childpid = 0; /* child should have finished */
}
else
fileerror("illegal token in file",tok,fp);
}
}
/* reads the points array of an obect in from a file */
void readpoints(struct object *nobj, int fp)
{
struct point pt[MAX_POINTS_PER_OBJECT];
int i=0;
char buf[100];
#if DEBUG
printf("Reading points\n");
#endif
do {
ntoken(fp,buf);
if (strcmp(buf,"}")) {
if (i >= MAX_POINTS_PER_OBJECT)
fileerror("Maximum points per object limit reached",
"",fp);
pt[i].x=(float)atof(buf);
ntoken(fp,buf);
pt[i].y=(float)atof(buf);
ntoken(fp,buf);
pt[i].z=(float)atof(buf);
i++;
}
} while(strcmp(buf,"}"));
nobj->pcount=i;
nobj->points=(struct point *)calloc(i,sizeof(struct point));
memcpy(nobj->points,pt,i*sizeof(struct point));
/* allocate space for world-coord points and perspective transformed
* points. */
nobj->cpoints=(struct point *)calloc(i,sizeof(struct point));
nobj->ppoints=(XPoint *)calloc(i,sizeof(XPoint));
}
/* reads a face of an object and it's list of points from a file */
void readface(struct object *nobj, int fp)
{
struct polygon *npoly;
int pt[MAX_POINTS_PER_FACE];
int i=0;
char tok[100];
if (nobj->fcount >= MAX_FACES_PER_OBJECT)
fileerror("Maximum faces per object limit reached","",fp);
#if DEBUG
printf("Reading face\n");
#endif
npoly=(struct polygon *)malloc(sizeof(struct polygon));
/* read in colour */
ntoken(fp,tok);
npoly->colour=atol(tok);
/* read in and assign face style */
ntoken(fp,tok);
switch(tok[0]) {
case 'f':
npoly->type=f_face;
break;
case 'p':
npoly->type=f_plane;
break;
case 'l':
npoly->type=f_line;
break;
case 'w':
npoly->type=f_wireframe;
break;
case 'g':
npoly->type=f_glass;
break;
case 'c':
npoly->type=f_sphere;
break;
case 'd':
npoly->type=f_point;
break;
case 's':
npoly->type=f_shaded;
break;
default:
fileerror("Unknown face type",tok,fp);
break;
}
/* read in list of points making up the face */
ntoken(fp,tok); /* get { */
do {
if (i >= MAX_POINTS_PER_FACE)
fileerror("Maximum points per face limit reached","",fp);
ntoken(fp,tok);
if (strcmp(tok,"}")) {
pt[i]=atoi(tok);
if (pt[i] >= nobj->pcount)
fileerror("Attempted to use a non-existant point",
"",fp);
i++;
}
} while(strcmp(tok,"}"));
if (i < 3 && npoly->type==f_face)
fileerror("A face must have at least 3 points","",fp);
if (i != 2 && npoly->type==f_sphere)
fileerror("A sphere face must have only 2 points","",fp);
if (npoly->type == f_sphere) {
/* calculate the radius of the sphere.
*/
float xd,yd,zd;
xd = nobj->points[pt[0]].x - nobj->points[pt[1]].x;
yd = nobj->points[pt[0]].y - nobj->points[pt[1]].y;
zd = nobj->points[pt[0]].z - nobj->points[pt[1]].z;
npoly->radius = sqrt(xd*xd + yd*yd + zd*zd);
}
npoly->pcount=i;
npoly->vertices=(int *)calloc(i,sizeof(int));
memcpy(npoly->vertices,pt,i*sizeof(int));
memcpy(nobj->faces+(nobj->fcount++),npoly,sizeof(struct polygon));
#if DEBUG
printf("points - %d. type - %d. colour - %d\n",
npoly->pcount,npoly->type,npoly->colour);
#endif
}
/* copy one vehicle into another.
*
* nv - destination of copy
* copy - source of copy
* ohead - head of the object list
*/
void copyvehicle(struct vehicle *nv, struct vehicle *copy,
struct object **ohead)
{
int o,s;
/* do the copying */
nv->partcount = copy->partcount;
nv->type = copy->type;
nv->owner = copy->owner;
nv->weapon = copy->weapon;
nv->flying = copy->flying;
nv->name = strdupe(copy->name);
nv->velocity = copy->velocity;
nv->angle = copy->angle;
nv->angle_vel = copy->angle_vel;
nv->hp = copy->hp;
nv->max = copy->max;
nv->transfer = copy->transfer;
nv->ammo = copy->ammo;
nv->vm9vid = copy->vm9vid;
nv->buildervid = copy->buildervid;
nv->turret_ang = copy->turret_ang;
nv->seed = strdupe(copy->seed);
nv->pnum = copy->pnum;
nv->lasthit = copy->lasthit;
nv->spinrandom = copy->spinrandom;
if (nv->spinrandom) {
nv->xspin_vel = ((rand()%1000)/1000.0) * copy->xspin_vel;
nv->yspin_vel = ((rand()%1000)/1000.0) * copy->yspin_vel;
nv->zspin_vel = ((rand()%1000)/1000.0) * copy->zspin_vel;
}
else {
nv->xspin_vel = copy->xspin_vel;
nv->yspin_vel = copy->yspin_vel;
nv->zspin_vel = copy->zspin_vel;
}
/* copy brain */
nv->currentstate = copy->currentstate;
nv->stcount = copy->stcount;
nv->states = dupe(copy->states,
MAX_STATES_PER_VEHICLE*sizeof(struct state));
nv->lastvid = copy->lastvid;
nv->ftimer = copy->ftimer;
nv->bumped = copy->bumped;
for(s=0; s<nv->stcount; s++) {
int l;
nv->states[l].links = dupe(nv->states[l].links,
nv->states[l].lcount*sizeof(struct link));
}
/* copy all parts, adding the copies to the parts list */
for(o=0; o<nv->partcount; o++) {
struct object *obcpy;
int p,i;
nv->parts[o]=dupe(copy->parts[o],sizeof(struct object));
obcpy=nv->parts[o];
obcpy->next=(*ohead);
(*ohead)=obcpy;
obcpy->parent=nv;
obcpy->points=dupe(obcpy->points,
MAX_POINTS_PER_OBJECT*sizeof(struct point));
obcpy->cpoints=dupe(obcpy->cpoints,
MAX_POINTS_PER_OBJECT*sizeof(struct point));
obcpy->ppoints=dupe(obcpy->ppoints,
MAX_POINTS_PER_OBJECT*sizeof(XPoint));
obcpy->faces=dupe(obcpy->faces,
MAX_FACES_PER_OBJECT*sizeof(struct polygon));
obcpy->oscli=dupe(obcpy->oscli,
MAX_OSCLI_PER_OBJECT*sizeof(struct oscillate));
/* need to change the copied oscli so that the new pointers
* in it point to the points in the copied object.
*/
for(i=0; i<obcpy->ocount; i++) {
int pnum;
pnum=obcpy->oscli[i].pnum;
if (pnum == -1) {
obcpy->oscli[i].pt = &(obcpy->pos);
}
else {
obcpy->oscli[i].pt = &(obcpy->points[pnum]);
}
}
/* copy the vertex lists */
for(p=0; p<obcpy->fcount; p++) {
obcpy->faces[p].vertices = dupe(obcpy->faces[p].vertices,
obcpy->faces[p].pcount * sizeof(int));
}
}
}
struct vehicle *findbycode(struct vehicle *vh, char *code)
{
for(; vh && strcmp(vh->code,code); vh=vh->next)
;
if (vh)
return vh;
else {
printf("vehicle %s not found!! this should never happen.\n",code);
exit(20);
}
}
/* rotate the points of an object around the z-axis */
void readrotate(struct object *ob, int fp)
{
char tok[100];
double ang;
ntoken(fp,tok);
ang=atof(tok);
rotatez(ob,dtor(ang));
}
/* scale the points of the object along the x,y and z axes */
void readscale(struct object *ob, int fp)
{
char tok[100];
float x,y,z;
int i;
/* read scale factors */
ntoken(fp,tok);
x = atof(tok);
ntoken(fp,tok);
y = atof(tok);
ntoken(fp,tok);
z = atof(tok);
/* apply them */
for(i=0; i<ob->pcount; i++) {
ob->points[i].x *= x;
ob->points[i].y *= y;
ob->points[i].z *= z;
}
}
void readspin(struct vehicle *nv, int fp)
{
char tok[100];
/* read spin velocities */
ntoken(fp,tok);
if (!strcmp(tok,"random")) {
/* Set spinrandom, to indicate that all copies of this vehicle
* have a random spin in the range given by the spin of this
* vehicle.
*/
nv->spinrandom = True;
ntoken(fp,tok);
}
nv->xspin_vel = dtor(atof(tok));
ntoken(fp,tok);
nv->yspin_vel = dtor(atof(tok));
ntoken(fp,tok);
nv->zspin_vel = dtor(atof(tok));
}
/* wastecpp - when a parsing error of some kind occurs, fileerror() will
* signal the child process set up to fork off cpp. wastecpp() gets called
* and kills cpp and itself.
*/
static void wastecpp(int sig)
{
kill(childpid,SIGTERM);
exit(0);
}
/* returns a file descriptor that recieves the output of the command
* given by com, with argument file.
*/
int pipethrough(char *com, char *file)
{
int pfds[2];
char *argv[20];
int i = 1;
/* break com into command and arguments for execv */
argv[0] = strtok(com," \t");
while((argv[i++] = strtok(NULL," \t")) != NULL)
;
argv[i-1] = file;
argv[i] = NULL;
/* set up a pipe. The forked process writes to the pipe, and the
* reading end is returned to the caller.
*/
pipe(pfds);
if ((childpid = fork()) == 0) {
int status;
/* set up a signal handler, so that when fileerror() signals
* this process to die, cpp can be killed too. */
signal(SIGTERM,wastecpp);
/* We want to do our own child reaping so we can wait(). */
signal(SIGCHLD,SIG_DFL);
/* Re-direct stdout to go through the pipe instead */
close(1);
dup(pfds[1]);
if ((childpid = fork()) == 0) {
execv(argv[0],argv);
printf("execv returned??\n");
exit(100);
}
wait(&status);
if (status) {
/* Cpp exited with an error status. */
printf("CPP error!\n");
exit(1);
}
/* add an 'end', to indicate to readfile() that this vehicle is done */
nprintf(pfds[1],"end\n");
exit(0);
}
return pfds[0];
}
/* Read in one of the maximums for a vehicle.
*/
void readmax(struct vehicle *nv, int fp)
{
char tok[100];
ntoken(fp,tok);
if (!strcmp(tok,"velocity")) {
ntoken(fp,tok);
nv->max.velocity = atof(tok);
}
else if (!strcmp(tok,"angle_vel")) {
ntoken(fp,tok);
nv->max.angle_vel = atof(tok);
}
else if (!strcmp(tok,"altitude")) {
ntoken(fp,tok);
nv->max.altitude = atof(tok);
}
else if (!strcmp(tok,"turret_ang")) {
ntoken(fp,tok);
nv->max.turret_ang = atof(tok);
}
else if (!strcmp(tok,"treeheight")) {
ntoken(fp,tok);
nv->max.treeheight = atoi(tok);
}
}
/* createstars - create a list of stars, and add it to the map.
*
* mp - map to add the stars to
* scount - number of stars to create
*/
void createstars(struct map *mp, int scount)
{
int i;
int r;
mp->stars = (struct star *)calloc(scount,sizeof(struct star));
mp->scount = scount;
srand(scount);
for(i=0; i<scount; i++) {
mp->stars[i].bearing = dtor((rand()%3600) / 10.0);
if (mp->ground)
mp->stars[i].elevation = dtor((rand()%900) / 10.0);
else
mp->stars[i].elevation = dtor((rand()%1800) / 10.0 - 90);
mp->stars[i].intensity = (rand()%16) + 16;
r = rand()%10;
mp->stars[i].radius = (r <= 6) ? (1) : (r - 6);
}
}
void readvehiclescale(struct vehicle *nv, int fp)
{
float xs,ys,zs;
int i,j;
char tok[100];
/* read scale factors.
*/
ntoken(fp,tok);
xs = atof(tok);
ntoken(fp,tok);
ys = atof(tok);
ntoken(fp,tok);
zs = atof(tok);
/* scale all objects in the vehicle.
*/
for(i=0; i<nv->partcount; i++) {
struct object *ob;
ob = nv->parts[i];
for(j=0; j<ob->pcount; j++) {
ob->points[j].x *= xs;
ob->points[j].y *= ys;
ob->points[j].z *= zs;
}
}
}